
#ifndef _NEBULA_SDK__MANAGEDSERVICEIMPL_H_
#define _NEBULA_SDK__MANAGEDSERVICEIMPL_H_

#include "ServiceBase.h"


namespace nebula { namespace sdk {

//////////////////////////////////////////////////////////////////////////
template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::Initialize()
{
	return NEBULA_ERR_SUCCESS;
}

template<typename ServiceType>
void ManagedService<ServiceType>::Finalize()
{
}

template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::Start()
{
	return StartThreadPool();
}

template<typename ServiceType>
void ManagedService<ServiceType>::Stop()
{
	 StopThreadPool();
}

template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::StartThreadPool()
{
	typename PushSlotMap::iterator i = _push_slot_table.begin();
	for(; i != _push_slot_table.end(); ++i)
	{
		(*i).second->Start(static_cast<ServiceType*>(this));
	}
	return NEBULA_ERR_SUCCESS;
}

template<typename ServiceType>
void ManagedService<ServiceType>::StopThreadPool()
{
	typename PushSlotMap::iterator i = _push_slot_table.begin();
	for(; i != _push_slot_table.end(); ++i)
	{
		(*i).second->Stop();
	}
}

//////////////////////////////////////////////////////////////////////////
template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::RegisterPushSlot(
	const char* name, member_task_alloc alloc, push_handler handler, 
	unsigned min_thread, unsigned max_thread
	)
{
	//forward the call to static function version
	return RegisterPushSlot(
		name, _allocator.GetAgent(alloc), 
		handler, min_thread, max_thread
		);
}

template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::RegisterPushSlot(
	const char* name, static_task_alloc alloc, push_handler handler, 
	unsigned min_thread, unsigned max_thread
	)
{
	typename PushSlotMap::iterator findret = _push_slot_table.find(name);
	if (findret != _push_slot_table.end())
		return NEBULA_ERR_CONFLICT_RECORD;

	std::string proc_name(name);
	proc_name += "-handler";

	PushSlotDescRptr pushslotdesc = new PushSlotDesc(name, handler, min_thread, max_thread);
	NEBULA_ERROR_CODE rc = ServiceBase::RegisterPushSlot(name, alloc, &(pushslotdesc->queue));
	if (rc != NEBULA_ERR_SUCCESS)
		return rc;

	_push_slot_table.insert(std::make_pair(std::string(name), pushslotdesc));

	return NEBULA_ERR_SUCCESS;
}

template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::RegisterPopSlot(
	const char* name, IDoneTaskQueue** queue
	)
{
	return ServiceBase::RegisterPopSlot(name, queue);	
}

template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::RegisterQuerySlot(
	const char* name, query_handler  handler)
{
	return ServiceBase::RegisterQuerySlot(name, _querier.GetAgent(handler));
}

template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::RegisterDeleteSlot(
		const char* name, delete_handler handler)
{
	return ServiceBase::RegisterDeleteSlot(name, _deleter.GetAgent(handler));
}

template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::RegisterUpdateSlot(
		const char* name, member_task_alloc alloc, update_handler handler)
{
	//forward the call to static function version
	return RegisterUpdateSlot(
		name, _allocator.GetAgent(alloc), handler);
}

template<typename ServiceType>
NEBULA_ERROR_CODE ManagedService<ServiceType>::RegisterUpdateSlot(
	const char* name, static_task_alloc alloc, update_handler handler)
{
	return ServiceBase::RegisterUpdateSlot(
		name, alloc, _updater.GetAgent(handler));
}


}} // end of nebula::sdk

#endif // _NEBULA_SDK__MANAGEDSERVICEIMPL_H_


